<?php
/**
 * Created by PhpStorm.
 * User: i5_131009a
 * Date: 2015/12/18
 * Time: 10:39
 */
require_once GM_LIBRARY."/ExcelRead.class.php";

/**
 * 数据处理类
 * Class dataProcess
 */
class dataProcess {
    /**
     * @var 当前行数
     */
    private $currentDataLine;
    /**
     * @var 来源表路径
     */
    private $sourceDataPath;
    /**
     * @var 格式配置
     */
    private $formatConfig;
    /**
     * @var 错误列表
     */
    private $errorList;
    /**
     * @var
     */
    protected $excelRead;

    function __construct()
    {
        if (!is_null($this->excelRead)) {
            unset($this->excelRead);
        }
    }


    /**
     * 初始化
     * @param $formatArray 格式配置数组
     * @param $dataPath 数据来源路径
     * @return bool
     */
    function initialize($formatArray, $dataPath)
    {
        $this->errorList = array();
        $this->currentDataLine = 0;
        $this->sourceDataPath = $dataPath;
        $this->formatConfig = $formatArray;

        if($formatArray === false)
        {
            $errorTemp["code"] = -9;
            $errorTemp["msg"] = "格式配置文件错误";
            $this->errorList[] = $errorTemp;
            return false;
        }

        if(!$this->checkFormat($formatArray)){
            return false;
        }
        $excelRead = new ExcelRead();
        if(!$excelRead->initialize($dataPath,$formatArray["sheet"],$formatArray["rowSet"]["columnNameRow"],$formatArray["rowSet"]["dataStartRow"])){
            $errorTemp["code"] = -8;
            $errorTemp["msg"] = "excelRead 初始化失败";
            $this->errorList[] = $errorTemp;
            return false;
        }
        $columnNameList = $excelRead->getColumnNameList();
        if(!$this->formatValidityCheck($formatArray,$columnNameList)){
            return false;
        }


        $this->excelRead = $excelRead;
        return true;
    }

    /**
     * 设置格式配置
     * @param $formatConfig
     * @param null $field
     */
    function setFormatConfig($formatConfig, $field = null){
        if(is_null($field)){
            $this->formatConfig = $formatConfig;
        }else{
            $this->formatConfig[$field] = $formatConfig;
        }
    }

    /**
     * 获取下一条数据
     * @return array|bool
     */
    function getNextRow()
    {
        $rowData = $this->excelRead->getOneRowData($this->currentDataLine++);
        if($rowData === false){
            return false;
        }
        $formatRowData = array();
        foreach($this->formatConfig["columnSet"] as $columnName => $columnParameter){
            $formatRowData[$columnName] = $this->rowDataProcess($rowData,$columnName,$columnParameter);
        }
        return $formatRowData;
    }

    function getExcelCurrentLineNum(){
        return $this->currentDataLine + $this->formatConfig["rowSet"]["dataStartRow"];
    }

    /**
     * @param $rowData
     * @param $columnName
     * @param $columnParameter
     * @return mixed
     */
    function rowDataProcess($rowData, $columnName, $columnParameter){
        $columnParameter = is_array($columnParameter) ? $columnParameter : [$columnParameter];
        $parameter = array();
        foreach($columnParameter as $oneParameter){
            switch(substr($oneParameter,0,1)){
                case '$':
                    $parameter[] = substr($oneParameter,1,strlen($oneParameter));
                    break;
                default:
                    $parameter[] = $rowData[$oneParameter];
            }
        }
        if(isset($this->formatConfig["functionSet"][$columnName])){
            $functionName = $this->formatConfig["functionSet"][$columnName];
            return $this->$functionName($parameter);
        }else{
            return $parameter[0];
        }
    }


    /**
     *
     */
    function __destruct()
    {
        if(!is_null($this->excelRead)){
            unset($this->excelRead);
        }
    }

    /**
     * 获取错误列表
     * @return mixed
     */
    function getErrorList(){
        return $this->errorList;
    }

    /**
     * 获取格式配置
     * @param null $field
     * @return null
     */
    function getFormatConfig($field = null)
    {
        if(is_null($field)){
            return $this->formatConfig;
        }else{
            if(isset($this->formatConfig[$field])){
                return $this->formatConfig[$field];
            }else{
                return null;
            }
        }
    }


    /**
     * 格式配置合法性检查
     * @param $formatArray
     * @param $columnNameList
     * @return bool
     */
    function formatValidityCheck($formatArray, $columnNameList)
    {
        $error = array();
        if(isset($formatArray["functionSet"])){
            foreach($formatArray["functionSet"] as $columnName => $columnFunction){
                if(!method_exists(__CLASS__ ,$columnFunction))
                {
                    $errorMsg["code"] = -7;
                    $errorMsg["msg"] = "$columnFunction 方法不存在";
                    $error[] = $errorMsg;
                }else{
                    $checkFunctionName = "{$columnFunction}Check";
                    if(method_exists(__CLASS__,$checkFunctionName)){
                        if(!$this->$checkFunctionName($formatArray["columnSet"][$columnName])){
                            $errorMsg["code"] = -11;
                            $errorMsg["msg"] = "$columnFunction 参数错误";
                            $error[] = $errorMsg;
                        }
                    }
                }
            }
        }
        if (isset($formatArray["columnSet"])) {
            $columnFormatNameList = array();
            foreach ($formatArray["columnSet"] as $columnName) {
                if (is_array($columnName)) {
                    $columnFormatNameList = array_merge($columnFormatNameList, $columnName);
                } else {
                    $columnFormatNameList[] = $columnName;
                }
            }

            foreach ($columnFormatNameList as $columnFormatName) {
                switch(substr($columnFormatName,0,1)){
                    case '$':
                        break;
                    default:
                        if (!in_array($columnFormatName, $columnNameList)) {
                            $errorMsg["code"] = -10;
                            $errorMsg["msg"] = "$columnFormatName 列不存在";
                            $error[] = $errorMsg;
                        }
                }
            }
        } else {
            $this->formatConfig["columnSet"] = array_combine($columnNameList,$columnNameList);
        }

        if(!isset($formatArray["columnSet"])){
            $this->formatConfig["columnSet"] = array_combine($columnNameList,$columnNameList);
        }


        if(count($error) == 0)
        {
            return true;
        }else
        {
            $this->errorList = array_merge($this->errorList,$error);
            return false;
        }
    }

    /**
     * 读取格式配置文件
     * @param $formatPath
     * @return bool|mixed
     */
    function readFormatFile($formatPath)
    {
        if(!file_exists($formatPath))
        {
            echo $formatPath ."不存在";
            return false;
        }
        $configStr = file_get_contents($formatPath);

        $formatArray = json_decode($configStr,true);
        if(!isset($formatArray["rowSet"]["displauNameRow"])){
            $formatArray["rowSet"]["displauNameRow"] = null;
        }
        return is_null($formatArray) ? false : $formatArray;
    }

    /**
     * 检查格式配置
     * @param $formatArray
     * @return bool
     */
    function checkFormat($formatArray)
    {
        $error = array();
        if(!isset($formatArray["rowSet"])) {
            $errorMsg["code"] = -2;
            $errorMsg["msg"] = "行信息未设定";
            $error[] = $errorMsg;
        }
        else{
            if(!isset($formatArray["rowSet"]["dataStartRow"])){
                $errorMsg["code"] = -4;
                $errorMsg["msg"] = "表起始行未设定";
                $error[] = $errorMsg;
            }
            if(!isset($formatArray["rowSet"]["columnNameRow"])){
                $errorMsg["code"] = -5;
                $errorMsg["msg"] = "列名行为设定";
                $error[] = $errorMsg;
            }
        }

        if(isset($formatArray["functionSet"])){
            foreach($formatArray["functionSet"] as $columnName => $columnFunction){
                if(!array_key_exists($columnName,$formatArray["columnSet"])){
                    $errorMsg["code"] = -6;
                    $errorMsg["msg"] = "$columnName 列名不存在";
                    $error[] = $errorMsg;
                }
                if(!method_exists(__CLASS__,$columnFunction))
                {
                    $errorMsg["code"] = -7;
                    $errorMsg["msg"] = "$columnFunction 方法不存在";
                    $error[] = $errorMsg;
                }
            }
        }

        if(count($error) == 0)
        {
            return true;
        }else
        {
            $this->errorList = array_merge($this->errorList,$error);
            return false;
        }
    }


    /**
     * json方法 的格式配置检查方法
     * @param $setArray
     * @return bool
     */
    static function jsonCheck($setArray)
    {
        $arrayCount = count($setArray);
        if($arrayCount < 0)//数组数量大于0并且是偶数
        {
            return false;
        }

        if(($arrayCount % 2) != 0)
        {
            return false;
        }
        return true;
    }

    /**
     * 数据json
     * @param $array
     * @return string
     */
    static function json($array)
    {
        $count = count($array);
        $data = array();
        for($i = 0; $i < $count; $i = $i + 2){
            if(!is_null($array[$i + 1])){
                $data[$array[$i]] = $array[$i + 1];
            }else{
                $data[$array[$i]] = "";
            }

        }
        return json_encode($data);
    }


    /**
     * 删除头尾中括号 "[]"
     * @param $data
     * @return string
     */
    static function trimBracket($data){
        $data[0] = ltrim($data[0],'[');
        $data[0] = rtrim($data[0],']');
        return $data[0];
    }

}